/**
 * Created by mooshroom on 2016/7/2.
 */

//扩展数组操作函数：插入函数
Array.prototype.insert = function (index, item) {
    this.splice(index, 1, item);
};

//遍历函数
function ForEach(obj, func) {
    if (typeof obj == "object") {
        if (obj.length == undefined) {
            for (var i in obj) {
                func(obj[i], i);
            }
        } else {
            for (var i = 0; i < obj.length; i++) {
                func(obj[i], i);
            }
        }
    } else {
        console.log('类型错误:' + JSON.stringify(obj))
    }
}

avalon.ready(function () {
    var vm = avalon.define({
        $id: 'game',
        ready: function () {

            vm.startListen()
            avalon.scan()
        },
        reset: function () {
            avalon.mix(vm,{
                startTime:'',
                nowTime:'',
                step:0,

            })
        },


        //从图片构建拼图块
        imgSrc: 'http://www.kuaihou.com/d/file/201503/bf35f1e22ac390748b5bdc3668a2de0c.jpg',
        blocksNum: [
            0,
            1, 2, 3,
            4, 5, 6,
            7, 8, 9
        ],

        //操作监听
        startListen: function () {
            /*
             * Left
             Up
             Right
             Down
             */
            var ctrl = ['up', 'down', 'left', 'right']
            ForEach(ctrl, function (el) {
                shortcut.add(el, function () {
                    vm.moveTo(el)
                })
            })

        },

        //移动 @params tar 方向：up down left right

        moveTo: function (tar) {
            //获取0号机所在位置
            var list = vm.blocksNum
            var i = 0
            ForEach(list, function (el, index) {
                if (el == 0) {
                    i = index
                }
            })

            //不可走判断
            var cant = {
                down: [0, 2, 3],
                up: [7, 8, 9],
                right: [0, 1, 4, 7],
                left: [0, 3, 6, 9]
            }
            var can = true
            ForEach(cant[tar], function (el) {
                if (i == el) {
                    can = false
                }
            })
            if (!can) {
                return
            }

            //那么继续的话都是可以走的了
            var moveFN = {
                down: -3,
                up: 3,
                right: -1,
                left: 1
            }


            var target = i + moveFN[tar]

            //在0位的例外
            if (i == 0) {
                target = 1
            }
            //在1位的例外
            if(i==1&&tar=='down'){
                target=0
            }

            list.insert(i, list[target])
            list.insert(target, 0)

            //统计步数
            vm.step++


        },

        //随机移动
        pigMove: function (times) {

            vm.step=0
            function pig(){
                var ctrl = ['up', 'down', 'left', 'right']
                var num=(Math.random()*100).toFixed(0)%4
                vm.moveTo(ctrl[num])


                if(vm.step==times){
                    //开始计时
                    vm.reset()
                    vm.start()
                    return
                }
                setTimeout(pig,1)
            }

                pig()



        },

        //开始计时
        startTime:'',
        nowTime:'',
        costTime:[0,0,0,0,0],
        timeInterval:'',
        step:0,
        start: function () {
            clearInterval(vm.timeInterval)
            vm.startTime=new Date().getTime()
            vm.timeInterval=setInterval(function () {
                var now=new Date().getTime()
                var cost=now-vm.startTime

                var d, h, m, s,ss
                if(cost>=1000){
                    s=(cost/1000).toFixed(0)
                    ss=cost%1000
                }

                if(s>=60){
                    m=(s/60).toFixed(0)
                    s=s%60
                }

                if(m>=60){
                    h=(m/60).toFixed(0)
                    m=m%60
                }
                if(h>=24){
                    d=(h/24).toFixed(0)
                    h=h%24
                }

                vm.costTime=[d,h,m,s,ss]


            },20)
        },

        //完成判断

        hasBeenCompleted: function () {
            var completed=true
            ForEach(vm.blocksNum, function (el,index) {
                if(el!=index){
                    completed=false
                }
            })

            if(completed){
                alert('恭喜完成！')
            }

        }

    })
    vm.ready()

    return window[vm.$id] = vm
})

window.shortcut = {
    'all_shortcuts': {},//All the shortcuts are stored in this array
    'add': function (shortcut_combination, callback, opt) {
        //Provide a set of default options
        var default_options = {
            'type': 'keydown',
            'propagate': false,
            'disable_in_input': false,
            'target': document,
            'keycode': false
        }
        if (!opt) opt = default_options;
        else {
            for (var dfo in default_options) {
                if (typeof opt[dfo] == 'undefined') opt[dfo] = default_options[dfo];
            }
        }


        var ele = opt.target;
        if (typeof opt.target == 'string') ele = document.getElementById(opt.target);
        var ths = this;
        shortcut_combination = shortcut_combination.toLowerCase();

        //先判断快捷键是否被绑定了，如果被绑定了则先解除绑定，再绑定新的
        if (this.all_shortcuts[shortcut_combination] != undefined) {
            this.remove(shortcut_combination)
            //console.log("快捷键"+shortcut_combination+"已替换为新的绑定")
        }


        //The function to be called at keypress
        var func = function (e) {
            e = e || window.event;

            if (opt['disable_in_input']) { //Don't enable shortcut keys in Input, Textarea fields
                var element;
                if (e.target) element = e.target;
                else if (e.srcElement) element = e.srcElement;
                if (element.nodeType == 3) element = element.parentNode;

                if (element.tagName == 'INPUT' || element.tagName == 'TEXTAREA') return;
            }

            //Find Which key is pressed
            if (e.keyCode) code = e.keyCode;
            else if (e.which) code = e.which;
            var character = String.fromCharCode(code).toLowerCase();

            if (code == 188) character = ","; //If the user presses , when the type is onkeydown
            if (code == 190) character = "."; //If the user presses , when the type is onkeydown

            var keys = shortcut_combination.split("+");
            //Key Pressed - counts the number of valid keypresses - if it is same as the number of keys, the shortcut function is invoked
            var kp = 0;

            //Work around for stupid Shift key bug created by using lowercase - as a result the shift+num combination was broken
            var shift_nums = {
                "`": "~",
                "1": "!",
                "2": "@",
                "3": "#",
                "4": "$",
                "5": "%",
                "6": "^",
                "7": "&",
                "8": "*",
                "9": "(",
                "0": ")",
                "-": "_",
                "=": "+",
                ";": ":",
                "'": "\"",
                ",": "<",
                ".": ">",
                "/": "?",
                "\\": "|"
            }
            //Special Keys - and their codes
            var special_keys = {
                'esc': 27,
                'escape': 27,
                'tab': 9,
                'space': 32,
                'return': 13,
                'enter': 13,
                'backspace': 8,

                'scrolllock': 145,
                'scroll_lock': 145,
                'scroll': 145,
                'capslock': 20,
                'caps_lock': 20,
                'caps': 20,
                'numlock': 144,
                'num_lock': 144,
                'num': 144,

                'pause': 19,
                'break': 19,

                'insert': 45,
                'home': 36,
                'delete': 46,
                'end': 35,

                'pageup': 33,
                'page_up': 33,
                'pu': 33,

                'pagedown': 34,
                'page_down': 34,
                'pd': 34,

                'left': 37,
                'up': 38,
                'right': 39,
                'down': 40,

                'f1': 112,
                'f2': 113,
                'f3': 114,
                'f4': 115,
                'f5': 116,
                'f6': 117,
                'f7': 118,
                'f8': 119,
                'f9': 120,
                'f10': 121,
                'f11': 122,
                'f12': 123,

                'addi': 107,
                'sub': 109
            }

            var modifiers = {
                shift: {wanted: false, pressed: false},
                ctrl: {wanted: false, pressed: false},
                alt: {wanted: false, pressed: false},
                meta: {wanted: false, pressed: false}	//Meta is Mac specific
            };

            if (e.ctrlKey)    modifiers.ctrl.pressed = true;
            if (e.shiftKey)    modifiers.shift.pressed = true;
            if (e.altKey)    modifiers.alt.pressed = true;
            if (e.metaKey)   modifiers.meta.pressed = true;

            for (var i = 0; k = keys[i], i < keys.length; i++) {
                //Modifiers
                if (k == 'ctrl' || k == 'control') {
                    kp++;
                    modifiers.ctrl.wanted = true;

                } else if (k == 'shift') {
                    kp++;
                    modifiers.shift.wanted = true;

                } else if (k == 'alt') {
                    kp++;
                    modifiers.alt.wanted = true;
                } else if (k == 'meta') {
                    kp++;
                    modifiers.meta.wanted = true;
                } else if (k.length > 1) { //If it is a special key
                    if (special_keys[k] == code) kp++;

                } else if (opt['keycode']) {
                    if (opt['keycode'] == code) kp++;

                } else { //The special keys did not match
                    if (character == k) kp++;
                    else {
                        if (shift_nums[character] && e.shiftKey) { //Stupid Shift key bug created by using lowercase
                            character = shift_nums[character];
                            if (character == k) kp++;
                        }
                    }
                }
            }

            if (kp == keys.length &&
                modifiers.ctrl.pressed == modifiers.ctrl.wanted &&
                modifiers.shift.pressed == modifiers.shift.wanted &&
                modifiers.alt.pressed == modifiers.alt.wanted &&
                modifiers.meta.pressed == modifiers.meta.wanted) {
                callback(e);

                if (!opt['propagate']) { //Stop the event
                    //e.cancelBubble is supported by IE - this will kill the bubbling process.
                    e.cancelBubble = true;
                    e.returnValue = false;

                    //e.stopPropagation works in Firefox.
                    if (e.stopPropagation) {
                        e.stopPropagation();
                        e.preventDefault();
                    }
                    return false;
                }
            }
        }
        this.all_shortcuts[shortcut_combination] = {
            'callback': func,
            'target': ele,
            'event': opt['type']
        };
        //Attach the function with the event
        if (ele.addEventListener) ele.addEventListener(opt['type'], func, false);
        else if (ele.attachEvent) ele.attachEvent('on' + opt['type'], func);
        else ele['on' + opt['type']] = func;
    },

    //Remove the shortcut - just specify the shortcut and I will remove the binding
    'remove': function (shortcut_combination) {
        shortcut_combination = shortcut_combination.toLowerCase();
        var binding = this.all_shortcuts[shortcut_combination];
        delete(this.all_shortcuts[shortcut_combination])
        if (!binding) return;
        var type = binding['event'];
        var ele = binding['target'];
        var callback = binding['callback'];

        if (ele.detachEvent) ele.detachEvent('on' + type, callback);
        else if (ele.removeEventListener) ele.removeEventListener(type, callback, false);
        else ele['on' + type] = false;
    }
}